#include "bsp_uart_fifo.h"

#include "Mini58Series.h"
#include "bsp.h"
#include "string.h"

UART_ST uartInfo[UART_NUM];

static void InitHardUart(void);

static void ConfigUartNVIC(void);

void bsp_InitUart(void) {
  InitHardUart();
  ConfigUartNVIC();
  memset(&uartInfo, 0, (sizeof(UART_ST) * UART_NUM));
  uartInfo[0].uart = UART0;
  uartInfo[1].uart = UART1;
}
//Get the parameters of the serial port number in the structure
UART_ST *bsp_uart_get_parm(uint8_t uart_num) { return &uartInfo[uart_num]; }

static void InitHardUart(void) {
#if UART0_EN == 1
  /* Enable IP clock */
  CLK_EnableModuleClock(UART0_MODULE);

  /* Select IP clock source */
  CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UARTSEL_HIRC,
                     CLK_CLKDIV_UART(1));

  /*---------------------------------------------------------------------------------------------------------*/
  /* Init I/O Multi-function */
  /*---------------------------------------------------------------------------------------------------------*/
  /* Set P1 multi-function pins for UART RXD, TXD */
  // SYS->P5_MFP |= SYS_MFP_P51_UART0_RXD | SYS_MFP_P50_UART0_TXD;
  SYS->P0_MFP |= SYS_MFP_P00_UART0_TXD | SYS_MFP_P01_UART0_RXD;
  /* Reset IP */
  SYS_ResetModule(SYS_IPRST1_UART0RST_Msk);
  /* Configure UART and set UART Baudrate */
  UART_Open(UART0, UART0_BAUD);
#endif

#if UART1_EN == 1
  /* Enable IP clock */
  CLK_EnableModuleClock(UART1_MODULE);

  /* Select IP clock source */
  CLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UARTSEL_HIRC,
                     CLK_CLKDIV_UART(1));

  /*---------------------------------------------------------------------------------------------------------*/
  /* Init I/O Multi-function */
  /*---------------------------------------------------------------------------------------------------------*/
  /* Set P1 multi-function pins for UART RXD, TXD */
  // SYS->P5_MFP |= SYS_MFP_P51_UART0_RXD | SYS_MFP_P50_UART0_TXD;
  SYS->P2_MFP |= SYS_MFP_P24_UART1_RXD | SYS_MFP_P25_UART1_TXD;
  /* Reset IP */
  SYS_ResetModule(SYS_IPRST1_UART1RST_Msk);
  /* Configure UART and set UART Baudrate */
  UART_Open(UART1, UART1_BAUD);
#endif
}

static void ConfigUartNVIC(void) {
#if UART0_EN == 1
  UART_ENABLE_INT(UART0, UART_INTEN_RDAIEN_Msk);
  NVIC_EnableIRQ(UART0_IRQn);
#endif
#if UART1_EN == 1
  UART_ENABLE_INT(UART1, UART_INTEN_RDAIEN_Msk);
  NVIC_EnableIRQ(UART1_IRQn);
#endif
}

void bsp_uart_send_byte(uint8_t uart_num, uint8_t byte) {
  UART_ST *pUart = NULL;
  pUart = &uartInfo[uart_num];
  while (pUart->uart->FIFOSTS & UART_FIFOSTS_TXFULL_Msk)
    ;
  pUart->uart->DAT = byte;
}

void bsp_uart_irq(UART_ST *pUart) {
  uint8_t ch_data = 0;
  if (pUart->uart->INTSTS & UART_INTSTS_RDAINT_Msk) {
    while (UART_IS_RX_READY(pUart->uart)) {
      ch_data = UART_READ(pUart->uart);
      pUart->rxBuf[pUart->pRxWrite++] = ch_data;
      pUart->pRxWrite %= UART_RX_BUF_LEN;
    }
  }
}

#if UART0_EN == 1
void UART0_IRQHandler(void) { bsp_uart_irq(&uartInfo[UART0_NUM]); }
#endif

#if UART1_EN == 1
void UART1_IRQHandler(void) { bsp_uart_irq(&uartInfo[UART1_NUM]); }
#endif
